﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DELVE_GAME
{
    class NetworkGame : Game
    {
        List<Turn> pendingTurns;
        int localPlayer;

        public NetworkGame(GameSettings gameSettings) 
            : base(gameSettings) { }

        public NetworkGame(GameSettings gameSettings, Board board)
            : base(gameSettings, board) { }

        //Sends turn data to other players
        public override void endTurn()
        {
            Turn toSubmit = gameLog.getLastTurn();
            gameLog.addAction((int)ACTIONS.END_TURN);
            if (!player.isAlive())
            {
                /*
                 * drop out of this computer's personal game
                 * this means that if we allow 3+ players,
                 * you'll be stuck waiting!
                 */
                eliminatePlayer(player);
            }
            else
            {
                //send to all other players
                sendTurn();
            }
            base.endTurn();
        }

        //Send turn to all other players
        private void sendTurn()
        {
            
        }

        /*
         * Receive turn from another player
         * Return true if this ends the game
         */
        public bool receiveTurn(Turn turn)
        {

            bool addTurn = true;
            foreach(Turn storedTurn in pendingTurns) 
            {
                if(storedTurn.playerIndex == turn.playerIndex) 
                {
                    addTurn = false;
                    break;
                }
            }
            bool gameOver = false;
            if (addTurn)
            {
                pendingTurns.Add(turn);
                gameOver = changeTurn();
            }
            return gameOver;
        }

        public override bool changeTurn()
        {
            bool gameOver = false;
            if (pendingTurns.Count == stillAlive.Count - 1)
            {
                while (pendingTurns.Count > 0)
                {
                    doTurn(pendingTurns[0]);
                    pendingTurns.RemoveAt(0);
                }
                barrier();
                foreach (Player p in players)
                {
                    if (!p.isAlive() && !stillAlive.Contains(p) &&
                        p.getPlayerIndex() != localPlayer)
                        //Local player isn't eliminated until after they get to see that they're gone
                        eliminatePlayer(p);
                }
                currentPlayer = localPlayer;
                player = players[currentPlayer];
                this.turn++;
                gameOver = isGameOver();
            }
            return isGameOver();
        }

        public void update()
        {
        }

        private void doTurn(Turn turn)
        {
            currentPlayer = turn.playerIndex;
            player = players[currentPlayer];
            Tile tile;
            int playerIndex;
            foreach (Action action in turn.actions)
            {
                switch (action.getActionIndex())
                {
                    case (int)ACTIONS.PLACE_BASES:
                        tile = board.getLocation(action.getLocation());
                        doMove(tile);
                        break;
                    case (int)ACTIONS.UPGRADE:
                        tile = board.getLocation(action.getLocation());
                        int upgrade = action.getUpgradeType();
                        applyUpgrade(tile, upgrade);
                        break;
                    case (int)ACTIONS.SEND_REQUEST:
                        playerIndex = action.getPlayerIndex();
                        sendAllianceRequest(playerIndex);
                        break;
                    case (int)ACTIONS.ACCEPT_REQUEST:
                        playerIndex = action.getPlayerIndex();
                        respondToRequest(playerIndex, true);
                        break;
                    case (int)ACTIONS.BREAK_ALLIANCE:
                        playerIndex = action.getPlayerIndex();
                        breakAlliance(playerIndex);
                        break;
                    case (int)ACTIONS.END_TURN:
                        break;
                }
            }
        }
    }
}
